<?php

class Group_Model_Member
{
	protected $_groupId = NULL;
	protected $_accountId = NULL;
	protected $_approveFlag = FALSE;
	protected $_roles = NULL;


    public function __construct(array $options = null)
    {
        if (is_array($options)) {
            $this->setOptions($options);
        }
    }


	public function setGroupId($groupId = NULL)
	{
		$this->_groupId = $groupId;
		return $this;
	}
	public function setAccountId($accountId = NULL)
	{
		$this->_accountId = $accountId;
		return $this;
	}
	public function setApproveFlag($approved = TRUE)
	{
		$this->_approveFlag = (bool)$approved;
		return $this;
	}

	public function getGroupId()
	{
		return $this->_groupId;
	}
	public function getAccountId()
	{
		return $this->_accountId;
	}
	public function getApproveFlag()
	{
		return $this->_approveFlag;
	}
	public function getRoles()
	{
		if (is_array($this->_roles) === FALSE) {
			$this->_loadRoles();
		}
		return $this->_roles;
	}

	public function addRole($role)
	{
		if (empty($role)) {
			return;
		}
		if (is_array($this->_roles) === FALSE) {
			$this->_loadRoles();
		}
		if (in_array($role, $this->_roles) === FALSE) {
			$table = Group_Model_DbTable_Role::getInstance();

			$dbData = array(
				'group_id' => $this->_groupId,
				'account_id' => $this->_accountId,
				'role' => $role,
			);

			$insertId = $table->insert($dbData);
			if (intval($insertId) === 0) {
				throw new Exception('Query error');
			}
		}
	}
	public function hasRole($role)
	{
		if (empty($role)) {
			return TRUE;
		}
		if (is_array($this->_roles) === FALSE) {
			$this->_loadRoles();
		}
		return in_array($role, $this->_roles);
	}


	public function _loadRoles()
	{
		$table = Group_Model_DbTable_Role::getInstance();

		$select = $table->select();
		$select
			->where('group_id= ?', $this->_groupId)
			->where('account_id= ?', $this->_accountId)
		;

		$dbResult = $table->fetchAll($select);

		$this->_roles = array();

		foreach ($dbResult as $dbRow) {
			$this->_roles[] = $dbRow->role;
		}
	}



    public function __set($name, $value)
    {
        $method = 'set' . ucfirst($name);
        $this->$method($value);
    }
    public function __get($name)
    {
        $method = 'get' . ucfirst($name);
        return $this->$method();
    }

    public function setOptions(array $options)
    {
        $methods = get_class_methods($this);
        foreach ($options as $key => $value) {
            $method = 'set' . ucfirst($key);
            if (in_array($method, $methods)) {
                $this->$method($value);
            }
        }
        return $this;
    }



	protected static $_instanceList = array();


	public static function groupHasMember($groupId, $accountId, $approvedOnly = TRUE)
	{
		$groupMember = self::groupGetMember($groupId, $accountId);
		return $groupMember === NULL ? FALSE : $approvedOnly === TRUE ? $groupMember->getApproveFlag() === TRUE : FALSE;
	}
	public static function groupGetMember($groupId, $accountId, $approvedOnly = TRUE)
	{
		if (intval($groupId) == 0 || intval($accountId) == 0) {
			return NULL;
		}


		if (is_array(self::$_instanceList) && isset(self::$_instanceList[$groupId])
			&& isset(self::$_instanceList[$groupId][$accountId]))
		{
			if ($approvedOnly) {
				if (self::$_instanceList[$groupId][$accountId]->getApproveFlag() === TRUE) {
					return self::$_instanceList[$groupId][$accountId];
				}
				return FALSE;
			}
			return self::$_instanceList[$groupId][$accountId];
		}

		$table = Group_Model_DbTable_Member::getInstance();

		$select = $table->select();
		//TODO: narrow this
		$select->where('group_id= ?', $groupId);

		$dbResult = $table->fetchAll($select);

		foreach ($dbResult as $dbRow) {
			if (is_array(self::$_instanceList[$dbRow->group_id]) === FALSE) {
				self::$_instanceList[$dbRow->group_id] = array();
			}

			if (isset(self::$_instanceList[$dbRow->group_id][$dbRow->account_id]) === FALSE) {
				$inst = new Group_Model_Member();
				$inst
					->setGroupId($dbRow->group_id)
					->setAccountId($dbRow->account_id)
					->setApproveFlag(intval($dbRow->approve_flag) === 1)
				;

				self::$_instanceList[$dbRow->group_id][$dbRow->account_id] = $inst;
			}
		}

		if (isset(self::$_instanceList[$groupId][$accountId]))
			return self::$_instanceList[$groupId][$accountId];

		return NULL;
	}

	public static function groupAddMember($groupId = NULL, $accountId = NULL)
	{
		if (intval($groupId) == 0 || intval($accountId) == 0) {
			return FALSE;
		}


		$groupMember = self::groupGetMember($groupId, $accountId);

		if ($groupMember instanceof Group_Model_Member) {
			//TODO: already member / waiting for approval
			return FALSE;
		}

		$table = Group_Model_DbTable_Member::getInstance();

		$dbData = array(
			'group_id' => $groupId,
			'account_id' => $accountId,
			'time' => time() - date('Z'),
			'approve_flag' => 1, //TODO: depends on group's settings
		);

		$insertId = $table->insert($dbData);
		if (intval($insertId) === 0) {
			throw new Exception('Query error');
		}

		$inst = new Group_Model_Member();

		$inst
			->setGroupId($groupId)
			->setAccountId($accountId)
			->setApproveFlag(1) //TODO: depends on group's settings
		;

		if (is_array(self::$_instanceList[$groupId]) === FALSE) {
			self::$_instanceList[$groupId] = array();
		}

		self::$_instanceList[$groupId][$accountId] = $inst;


		return TRUE;
	}

	public static function groupRemoveMember($groupId = NULL, $accountId = NULL)
	{
		if (intval($groupId) == 0 || intval($accountId) == 0) {
			return FALSE;
		}


		$table = Group_Model_DbTable_Member::getInstance();

		$updRows = $table->delete(array(
				'group_id= ?' => $groupId,
				'account_id= ?' => $accountId,
			));

		if ($updRows != 1) {
			return FALSE;
		}

		return TRUE;
	}

	public static function groupGetNewestMembers($groupId = NULL, $count = 10)
	{
		if (intval($groupId) <= 0) {
			return NULL;
		}


		$table = Group_Model_DbTable_Member::getInstance();

		//TODO: filters
		$select = $table->select();
		$select
			->where('group_id= ?', $groupId)
			->order('time DESC')
			->limit($count)
		;

		$dbResult = $table->fetchAll($select);


		$instances = array();

		foreach ($dbResult as $dbRow) {
			if (is_array(self::$_instanceList[$dbRow->group_id]) === FALSE) {
				self::$_instanceList[$dbRow->group_id] = array();
			}

			if (isset(self::$_instanceList[$dbRow->group_id][$dbRow->account_id]) === FALSE) {
				$inst = new Group_Model_Member();
				$inst
					->setGroupId($dbRow->group_id)
					->setAccountId($dbRow->account_id)
					->setApproveFlag(intval($dbRow->approve_flag) === 1)
				;

				self::$_instanceList[$dbRow->group_id][$dbRow->account_id] = $inst;
			}

			$instances[] = self::$_instanceList[$dbRow->group_id][$dbRow->account_id];
		}

		return $instances;
	}

	public static function memberGetNewestGroups($accountId = NULL, $count = 10)
	{
		if (intval($accountId) <= 0) {
			return NULL;
		}


		$table = Group_Model_DbTable_Member::getInstance();

		//TODO: filters
		$select = $table->select();
		$select
			->where('account_id= ?', $accountId)
			->order('time DESC')
			->limit($count)
		;

		$dbResult = $table->fetchAll($select);


		$instances = array();

		foreach ($dbResult as $dbRow) {
			if (is_array(self::$_instanceList[$dbRow->group_id]) === FALSE) {
				self::$_instanceList[$dbRow->group_id] = array();
			}

			if (isset(self::$_instanceList[$dbRow->group_id][$dbRow->account_id]) === FALSE) {
				$inst = new Group_Model_Member();
				$inst
					->setGroupId($dbRow->group_id)
					->setAccountId($dbRow->account_id)
					->setApproveFlag(intval($dbRow->approve_flag) === 1)
				;

				self::$_instanceList[$dbRow->group_id][$dbRow->account_id] = $inst;
			}

			$instances[] = self::$_instanceList[$dbRow->group_id][$dbRow->account_id];
		}

		return $instances;
	}
}
